package com.campus.secondhand.service.impl;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.stereotype.Service;

import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.MultiMatchQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.RangeQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.TermQuery;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.campus.secondhand.common.Result;
import com.campus.secondhand.entity.Product;
import com.campus.secondhand.entity.PurchaseRequest;
import com.campus.secondhand.entity.School;
import com.campus.secondhand.entity.User;
import com.campus.secondhand.entity.ProductImages;
import com.campus.secondhand.mapper.ProductMapper;
import com.campus.secondhand.mapper.PurchaseRequestMapper;
import com.campus.secondhand.mapper.SchoolMapper;
import com.campus.secondhand.mapper.UserMapper;
import com.campus.secondhand.mapper.ProductImageMapper;
import com.campus.secondhand.model.dto.SearchResultDTO;
import com.campus.secondhand.model.es.ProductDocument;
import com.campus.secondhand.model.es.PurchaseRequestDocument;
import com.campus.secondhand.model.es.SchoolDocument;
import com.campus.secondhand.model.es.UserDocument;
import com.campus.secondhand.model.vo.ProductVO;
import com.campus.secondhand.model.vo.PurchaseRequestVO;
import com.campus.secondhand.repository.es.ProductEsRepository;
import com.campus.secondhand.repository.es.PurchaseRequestEsRepository;
import com.campus.secondhand.repository.es.SchoolEsRepository;
import com.campus.secondhand.repository.es.UserEsRepository;
import com.campus.secondhand.service.SearchService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 搜索服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SearchServiceImpl implements SearchService {

    private final ProductEsRepository productEsRepository;
    private final PurchaseRequestEsRepository purchaseRequestEsRepository;
    private final SchoolEsRepository schoolEsRepository;
    private final UserEsRepository userEsRepository;
    private final ProductMapper productMapper;
    private final PurchaseRequestMapper purchaseRequestMapper;
    private final SchoolMapper schoolMapper;
    private final UserMapper userMapper;
    private final ElasticsearchOperations elasticsearchOperations;
    private final ProductImageMapper productImageMapper;

    private static final String PRODUCT_INDEX = "product";
    private static final String PURCHASE_REQUEST_INDEX = "purchase";
    private static final String SCHOOL_INDEX = "school";
    private static final String USER_INDEX = "user";

    /**
     * 目前因为es中数据太少，执行策略是找不到的都去数据库找，然后更新es
     * 实际应该服从es，只有更新新建删除商品时对es操作即可
     */
    @Override
    public Result<SearchResultDTO> search(String keyword, Integer page, Integer pageSize, String sortBy) {
        if (keyword == null || keyword.isEmpty()) {
            return Result.error("搜索关键词不能为空");
        }

        try {
            // 构建返回结果
            SearchResultDTO result = new SearchResultDTO();

            // 搜索商品（限制返回10条）
            Result<Map<String, Object>> productResult = searchProducts(keyword, 1, 10, sortBy, null, null, null, null);
            if (productResult.getCode() == 200 && productResult.getData() != null) {
                @SuppressWarnings("unchecked")
                List<ProductVO> products = (List<ProductVO>) productResult.getData().get("list");
                Object totalObj = productResult.getData().get("total");
                Integer totalProducts = 0;
                if (totalObj instanceof Integer) {
                    totalProducts = (Integer) totalObj;
                } else if (totalObj instanceof Long) {
                    totalProducts = ((Long) totalObj).intValue();
                } else if (totalObj instanceof String) {
                    totalProducts = Integer.parseInt((String) totalObj);
                }
                result.setProducts(products);
                result.setTotalProducts(totalProducts);
            }

            // 搜索求购信息（限制返回10条）
            Result<Map<String, Object>> purchaseRequestResult = searchPurchaseRequests(keyword, 1, 10, sortBy, null,
                    null, null, null);
            if (purchaseRequestResult.getCode() == 200 && purchaseRequestResult.getData() != null) {
                @SuppressWarnings("unchecked")
                List<PurchaseRequestVO> purchaseRequests = (List<PurchaseRequestVO>) purchaseRequestResult.getData()
                        .get("list");
                Object totalObj = purchaseRequestResult.getData().get("total");
                Integer totalPurchaseRequests = 0;
                if (totalObj instanceof Integer) {
                    totalPurchaseRequests = (Integer) totalObj;
                } else if (totalObj instanceof Long) {
                    totalPurchaseRequests = ((Long) totalObj).intValue();
                } else if (totalObj instanceof String) {
                    totalPurchaseRequests = Integer.parseInt((String) totalObj);
                }
                result.setPurchaseRequests(purchaseRequests);
                result.setTotalPurchaseRequests(totalPurchaseRequests);
            }

            // 搜索学校（限制返回5条）
            Result<Map<String, Object>> schoolResult = searchSchools(keyword, 1, 5);
            if (schoolResult.getCode() == 200 && schoolResult.getData() != null) {
                @SuppressWarnings("unchecked")
                List<School> schools = (List<School>) schoolResult.getData().get("list");
                Object totalObj = schoolResult.getData().get("total");
                int totalSchools = 0;
                if (totalObj instanceof Integer) {
                    totalSchools = (Integer) totalObj;
                } else if (totalObj instanceof Long) {
                    totalSchools = ((Long) totalObj).intValue();
                } else if (totalObj instanceof String) {
                    totalSchools = Integer.parseInt((String) totalObj);
                }
                result.setSchools(schools);
                result.setTotalSchools(totalSchools);
            }

            // 搜索用户（限制返回5条）
            Result<Map<String, Object>> userResult = searchUsers(keyword, 1, 5, null);
            if (userResult.getCode() == 200 && userResult.getData() != null) {
                @SuppressWarnings("unchecked")
                List<User> users = (List<User>) userResult.getData().get("list");
                Object totalObj = userResult.getData().get("total");
                int totalUsers = 0;
                if (totalObj instanceof Integer) {
                    totalUsers = (Integer) totalObj;
                } else if (totalObj instanceof Long) {
                    totalUsers = ((Long) totalObj).intValue();
                } else if (totalObj instanceof String) {
                    totalUsers = Integer.parseInt((String) totalObj);
                }
                result.setUsers(users);
                result.setTotalUsers(totalUsers);
            }

            return Result.success(result);
        } catch (Exception e) {
            log.error("综合搜索失败", e);
            return Result.error("搜索失败：" + e.getMessage());
        }
    }

    @Override
    public Result<Map<String, Object>> searchProducts(String keyword, Integer page, Integer pageSize,
            String sortBy, Long categoryId, Long schoolId,
            BigDecimal minPrice, BigDecimal maxPrice) {
        if (keyword == null || keyword.isEmpty()) {
            return Result.error("搜索关键词不能为空");
        }

        // 设置默认分页参数
        page = page != null ? page : 1;
        pageSize = pageSize != null ? pageSize : 12;

        try {
            // 使用ES仓库进行搜索
            List<ProductDocument> productDocuments = productEsRepository.searchProducts(
                    keyword, schoolId, categoryId, (page - 1) * pageSize, pageSize);

            // 如果ES中没有找到数据，尝试从数据库中搜索
            if (productDocuments == null || productDocuments.isEmpty()) {
                log.info("ES中未找到匹配的商品数据，尝试从数据库搜索");
                return fallbackSearchProducts(keyword, page, pageSize, sortBy, categoryId, schoolId, minPrice,
                        maxPrice);
            }

            // 转换为VO
            List<ProductVO> productVOs = productDocuments.stream()
                    .map(this::convertToProductVO)
                    .collect(Collectors.toList());

            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", productVOs);
            result.put("total", productVOs.size());

            return Result.success(result);
        } catch (Exception e) {
            log.error("搜索商品失败", e);
            // 降级处理：如果ES搜索失败，尝试使用数据库搜索
            return fallbackSearchProducts(keyword, page, pageSize, sortBy, categoryId, schoolId, minPrice, maxPrice);
        }
    }

    /**
     * 降级处理：使用数据库搜索商品
     * 如果数据库中找到结果，同时更新到ES中
     */
    private Result<Map<String, Object>> fallbackSearchProducts(String keyword, Integer page, Integer pageSize,
            String sortBy, Long categoryId, Long schoolId,
            BigDecimal minPrice, BigDecimal maxPrice) {
        try {
            log.warn("ES搜索失败或未找到数据，降级为数据库搜索");

            // 创建查询条件
            LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();

            // 关键词搜索
            queryWrapper.like(Product::getName, keyword)
                    .or()
                    .like(Product::getDescription, keyword);

            // 分类筛选
            if (categoryId != null) {
                queryWrapper.eq(Product::getCategoryId, categoryId);
            }

            // 学校筛选
            if (schoolId != null) {
                queryWrapper.eq(Product::getSchoolId, schoolId);
            }

            // 价格范围筛选
            if (minPrice != null) {
                queryWrapper.ge(Product::getPrice, minPrice);
            }

            if (maxPrice != null) {
                queryWrapper.le(Product::getPrice, maxPrice);
            }

            // 状态筛选 - 只查询在售商品
            queryWrapper.eq(Product::getStatus, 1)
                    .eq(Product::getDeleted, 0);

            // 排序
            if (sortBy != null) {
                switch (sortBy) {
                    case "priceAsc":
                        queryWrapper.orderByAsc(Product::getPrice);
                        break;
                    case "priceDesc":
                        queryWrapper.orderByDesc(Product::getPrice);
                        break;
                    case "newest":
                        queryWrapper.orderByDesc(Product::getCreatedAt);
                        break;
                    case "views":
                        queryWrapper.orderByDesc(Product::getViews);
                        break;
                    default:
                        queryWrapper.orderByDesc(Product::getCreatedAt);
                        break;
                }
            } else {
                queryWrapper.orderByDesc(Product::getCreatedAt);
            }

            // 执行分页查询
            Page<Product> productPage = new Page<>(page, pageSize);
            Page<Product> resultPage = productMapper.selectPage(productPage, queryWrapper);

            // 检查是否有搜索结果
            if (resultPage.getRecords() != null && !resultPage.getRecords().isEmpty()) {
                // 异步更新搜索结果到ES
                new Thread(() -> {
                    try {
                        log.info("开始将数据库搜索结果同步到ES，共{}条", resultPage.getRecords().size());
                        for (Product product : resultPage.getRecords()) {
                            createOrUpdateProductIndex(product.getId());
                        }
                        log.info("数据库搜索结果同步到ES完成");
                    } catch (Exception e) {
                        log.error("同步数据库搜索结果到ES失败", e);
                    }
                }).start();
            }

            // 转换为VO
            List<ProductVO> productVOs = resultPage.getRecords().stream()
                    .map(this::convertEntityToVO)
                    .collect(Collectors.toList());

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", productVOs);
            result.put("total", resultPage.getTotal());

            return Result.success(result);
        } catch (Exception e) {
            log.error("数据库搜索商品失败", e);
            return Result.error("搜索商品失败：" + e.getMessage());
        }
    }

    @Override
    public Result<Map<String, Object>> searchSchools(String keyword, Integer page, Integer pageSize) {
        if (keyword == null || keyword.isEmpty()) {
            return Result.error("搜索关键词不能为空");
        }

        // 设置默认分页参数
        page = page != null ? page : 1;
        pageSize = pageSize != null ? pageSize : 10;

        try {
            // 使用ES仓库进行搜索
            List<SchoolDocument> schoolDocuments = schoolEsRepository.searchSchools(
                    keyword, (page - 1) * pageSize, pageSize);

            // 如果ES中没有找到数据，尝试从数据库中搜索
            if (schoolDocuments == null || schoolDocuments.isEmpty()) {
                log.info("ES中未找到匹配的学校数据，尝试从数据库搜索");
                return fallbackSearchSchools(keyword, page, pageSize);
            }

            // 转换为School实体
            List<School> schools = schoolDocuments.stream()
                    .map(this::convertToSchool)
                    .collect(Collectors.toList());

            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", schools);
            result.put("total", schools.size());

            return Result.success(result);
        } catch (Exception e) {
            log.error("搜索学校失败", e);
            // 降级处理：如果ES搜索失败，尝试使用数据库搜索
            return fallbackSearchSchools(keyword, page, pageSize);
        }
    }

    /**
     * 降级处理：使用数据库搜索学校
     * 如果数据库中找到结果，同时更新到ES中
     */
    private Result<Map<String, Object>> fallbackSearchSchools(String keyword, Integer page, Integer pageSize) {
        try {
            log.warn("ES搜索失败或未找到数据，降级为数据库搜索");

            // 创建查询条件
            LambdaQueryWrapper<School> queryWrapper = new LambdaQueryWrapper<>();

            // 关键词搜索
            queryWrapper.like(School::getName, keyword)
                    .or()
                    .like(School::getAddress, keyword)
                    .or()
                    .like(School::getCity, keyword);

            // 执行分页查询
            Page<School> schoolPage = new Page<>(page, pageSize);
            Page<School> resultPage = schoolMapper.selectPage(schoolPage, queryWrapper);

            // 检查是否有搜索结果
            if (resultPage.getRecords() != null && !resultPage.getRecords().isEmpty()) {
                // 异步更新搜索结果到ES
                new Thread(() -> {
                    try {
                        log.info("开始将数据库搜索结果同步到ES，共{}条", resultPage.getRecords().size());
                        for (School school : resultPage.getRecords()) {
                            createOrUpdateSchoolIndex(school.getId());
                        }
                        log.info("数据库搜索结果同步到ES完成");
                    } catch (Exception e) {
                        log.error("同步数据库搜索结果到ES失败", e);
                    }
                }).start();
            }

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", resultPage.getRecords());
            result.put("total", resultPage.getTotal());

            return Result.success(result);
        } catch (Exception e) {
            log.error("数据库搜索学校失败", e);
            return Result.error("搜索学校失败：" + e.getMessage());
        }
    }

    @Override
    public Result<Map<String, Object>> searchUsers(String keyword, Integer page, Integer pageSize, Long schoolId) {
        if (keyword == null || keyword.isEmpty()) {
            return Result.error("搜索关键词不能为空");
        }

        // 设置默认分页参数
        page = page != null ? page : 1;
        pageSize = pageSize != null ? pageSize : 10;

        try {
            // 使用ES仓库进行搜索
            List<UserDocument> userDocuments = userEsRepository.searchUsers(
                    keyword, schoolId, (page - 1) * pageSize, pageSize);

            // 如果ES中没有找到数据，尝试从数据库中搜索
            if (userDocuments == null || userDocuments.isEmpty()) {
                log.info("ES中未找到匹配的用户数据，尝试从数据库搜索");
                return fallbackSearchUsers(keyword, page, pageSize, schoolId);
            }

            // 转换为User实体
            List<User> users = userDocuments.stream()
                    .map(this::convertToUser)
                    .collect(Collectors.toList());

            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", users);
            result.put("total", users.size());

            return Result.success(result);
        } catch (Exception e) {
            log.error("搜索用户失败", e);
            // 降级处理：如果ES搜索失败，尝试使用数据库搜索
            return fallbackSearchUsers(keyword, page, pageSize, schoolId);
        }
    }

    /**
     * 降级处理：使用数据库搜索用户
     * 如果数据库中找到结果，同时更新到ES中
     */
    private Result<Map<String, Object>> fallbackSearchUsers(String keyword, Integer page, Integer pageSize,
            Long schoolId) {
        try {
            log.warn("ES搜索失败或未找到数据，降级为数据库搜索");

            // 创建查询条件
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

            // 关键词搜索
            queryWrapper.like(User::getUsername, keyword)
                    .or()
                    .like(User::getNickname, keyword);

            // 学校筛选
            if (schoolId != null) {
                queryWrapper.eq(User::getSchoolId, schoolId);
            }

            // 状态筛选 - 只查询正常用户
            queryWrapper.eq(User::getStatus, 1);

            // 执行分页查询
            Page<User> userPage = new Page<>(page, pageSize);
            Page<User> resultPage = userMapper.selectPage(userPage, queryWrapper);

            // 检查是否有搜索结果
            if (resultPage.getRecords() != null && !resultPage.getRecords().isEmpty()) {
                // 异步更新搜索结果到ES
                new Thread(() -> {
                    try {
                        log.info("开始将数据库搜索结果同步到ES，共{}条", resultPage.getRecords().size());
                        for (User user : resultPage.getRecords()) {
                            createOrUpdateUserIndex(user.getId());
                        }
                        log.info("数据库搜索结果同步到ES完成");
                    } catch (Exception e) {
                        log.error("同步数据库搜索结果到ES失败", e);
                    }
                }).start();
            }

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", resultPage.getRecords());
            result.put("total", resultPage.getTotal());

            return Result.success(result);
        } catch (Exception e) {
            log.error("数据库搜索用户失败", e);
            return Result.error("搜索用户失败：" + e.getMessage());
        }
    }

    /**
     * 创建或更新学校索引
     */
    @Override
    public void createOrUpdateSchoolIndex(Long schoolId) {
        try {
            // 查询学校详情
            School school = schoolMapper.selectById(schoolId);
            if (school == null) {
                log.error("学校不存在，无法索引，schoolId: {}", schoolId);
                return;
            }

            // 转换为ES文档
            SchoolDocument document = convertToSchoolDocument(school);

            // 保存到ES
            boolean success = schoolEsRepository.saveSchool(document);
            if (success) {
                log.info("学校索引创建/更新成功，schoolId: {}", schoolId);
            } else {
                log.error("学校索引创建/更新失败，schoolId: {}", schoolId);
            }
        } catch (Exception e) {
            log.error("创建学校索引失败，schoolId: {}", schoolId, e);
        }
    }

    /**
     * 创建或更新用户索引
     */
    @Override
    public void createOrUpdateUserIndex(Long userId) {
        try {
            // 查询用户详情
            User user = userMapper.selectById(userId);
            if (user == null) {
                log.error("用户不存在，无法索引，userId: {}", userId);
                return;
            }

            // 转换为ES文档
            UserDocument document = convertToUserDocument(user);

            // 保存到ES
            boolean success = userEsRepository.saveUser(document);
            if (success) {
                log.info("用户索引创建/更新成功，userId: {}", userId);
            } else {
                log.error("用户索引创建/更新失败，userId: {}", userId);
            }
        } catch (Exception e) {
            log.error("创建用户索引失败，userId: {}", userId, e);
        }
    }

    /**
     * 同步所有学校到ES
     */
    @Override
    public Result<String> syncAllSchoolsToEs() {
        try {
            log.info("开始同步学校到ElasticSearch...");

            // 查询所有学校
            LambdaQueryWrapper<School> queryWrapper = new LambdaQueryWrapper<>();
            // 这里不需要状态筛选，因为School实体没有status字段

            List<School> schools = schoolMapper.selectList(queryWrapper);
            log.info("共找到{}所学校", schools.size());

            int successCount = 0;
            for (School school : schools) {
                try {
                    // 构建ES文档
                    SchoolDocument document = convertToSchoolDocument(school);

                    // 保存到ES
                    boolean success = schoolEsRepository.saveSchool(document);
                    if (success) {
                        successCount++;
                    }
                } catch (Exception e) {
                    log.error("同步学校#{}到ES失败", school.getId(), e);
                }
            }

            String resultMsg = String.format("同步完成，共%d所学校，成功%d所", schools.size(), successCount);
            log.info(resultMsg);
            return Result.success(resultMsg);
        } catch (Exception e) {
            log.error("同步学校到ES失败", e);
            return Result.error("同步失败：" + e.getMessage());
        }
    }

    /**
     * 同步所有用户到ES
     */
    @Override
    public Result<String> syncAllUsersToEs() {
        try {
            log.info("开始同步用户到ElasticSearch...");

            // 查询所有正常的用户
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getStatus, 1); // 正常状态

            List<User> users = userMapper.selectList(queryWrapper);
            log.info("共找到{}个正常用户", users.size());

            int successCount = 0;
            for (User user : users) {
                try {
                    // 构建ES文档
                    UserDocument document = convertToUserDocument(user);

                    // 保存到ES
                    boolean success = userEsRepository.saveUser(document);
                    if (success) {
                        successCount++;
                    }
                } catch (Exception e) {
                    log.error("同步用户#{}到ES失败", user.getId(), e);
                }
            }

            String resultMsg = String.format("同步完成，共%d个用户，成功%d个", users.size(), successCount);
            log.info(resultMsg);
            return Result.success(resultMsg);
        } catch (Exception e) {
            log.error("同步用户到ES失败", e);
            return Result.error("同步失败：" + e.getMessage());
        }
    }

    /**
     * 将学校实体转换为ES文档
     */
    private SchoolDocument convertToSchoolDocument(School school) {
        if (school == null) {
            return null;
        }

        SchoolDocument document = new SchoolDocument();
        document.setId(school.getId());
        document.setName(school.getName());
        document.setCity(school.getCity());
        document.setAddress(school.getAddress());
        document.setDescription(school.getDescription());
        document.setTags(school.getTags());
        document.setLogo(school.getLogo());
        document.setProvince(school.getProvince());
        document.setTransportation(school.getTransportation());

        return document;
    }

    /**
     * 将ES文档转换为学校实体
     */
    private School convertToSchool(SchoolDocument document) {
        if (document == null) {
            return null;
        }

        School school = new School();
        school.setId(document.getId());
        school.setName(document.getName());
        school.setCity(document.getCity());
        school.setAddress(document.getAddress());
        school.setDescription(document.getDescription());
        school.setTags(document.getTags());
        school.setLogo(document.getLogo());
        school.setProvince(document.getProvince());
        school.setTransportation(document.getTransportation());

        return school;
    }

    /**
     * 将用户实体转换为ES文档
     */
    private UserDocument convertToUserDocument(User user) {
        if (user == null) {
            return null;
        }

        // 查询学校信息
        School school = null;
        if (user.getSchoolId() != null) {
            school = schoolMapper.selectById(user.getSchoolId());
        }

        UserDocument document = new UserDocument();
        document.setId(user.getId());
        document.setUsername(user.getUsername());
        document.setNickname(user.getNickname());
        document.setAvatar(user.getAvatar());
        document.setSchoolId(user.getSchoolId());
        document.setIntroduction(user.getIntroduction());
        document.setMajor(user.getMajor());
        document.setRegion(user.getRegion());
        document.setStatus(user.getStatus());

        // 设置学校名称
        if (school != null) {
            document.setSchoolName(school.getName());
        }

        // 将日期时间字段转换为时间戳
        if (user.getCreatedAt() != null) {
            Long createdAtTimestamp = user.getCreatedAt()
                    .atZone(ZoneId.systemDefault())
                    .toInstant()
                    .toEpochMilli();
            document.setCreatedAt(createdAtTimestamp);
        }

        // 设置最后活跃时间（示例，根据实际情况修改）
        document.setLastActive(System.currentTimeMillis());

        return document;
    }

    /**
     * 将ES文档转换为用户实体
     */
    private User convertToUser(UserDocument document) {
        if (document == null) {
            return null;
        }

        User user = new User();
        user.setId(document.getId());
        user.setUsername(document.getUsername());
        user.setNickname(document.getNickname());
        user.setAvatar(document.getAvatar());
        user.setSchoolId(document.getSchoolId());
        user.setIntroduction(document.getIntroduction());
        user.setMajor(document.getMajor());
        user.setRegion(document.getRegion());
        user.setStatus(document.getStatus());

        // 处理创建时间
        if (document.getCreatedAt() != null) {
            LocalDateTime createdAt = LocalDateTime.ofInstant(
                    Instant.ofEpochMilli(document.getCreatedAt()),
                    ZoneId.systemDefault());
            user.setCreatedAt(createdAt);
        }

        return user;
    }

    @Override
    public void createOrUpdateProductIndex(Long productId) {
        try {
            // 查询商品详情
            Product product = productMapper.selectById(productId);
            if (product == null) {
                log.error("商品不存在，无法索引，productId: {}", productId);
                return;
            }

            // 转换为ES文档
            ProductDocument document = convertToDocument(product);

            // 保存到ES
            boolean success = productEsRepository.saveProduct(document);
            if (success) {
                log.info("商品索引创建/更新成功，productId: {}", productId);
            } else {
                log.error("商品索引创建/更新失败，productId: {}", productId);
            }
        } catch (Exception e) {
            log.error("创建商品索引失败，productId: {}", productId, e);
        }
    }

    @Override
    public Result<String> syncAllProductsToEs() {
        try {
            log.info("开始同步商品到ElasticSearch...");

            // 查询所有在售的商品
            LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Product::getStatus, 1) // 在售状态
                    .eq(Product::getDeleted, 0); // 未删除

            List<Product> products = productMapper.selectList(queryWrapper);
            log.info("共找到{}件在售商品", products.size());

            int successCount = 0;
            for (Product product : products) {
                try {
                    // 构建ES文档
                    ProductDocument document = convertToDocument(product);

                    // 保存到ES
                    boolean success = productEsRepository.saveProduct(document);
                    if (success) {
                        successCount++;
                    }
                } catch (Exception e) {
                    log.error("同步商品#{}到ES失败", product.getId(), e);
                }
            }

            String resultMsg = String.format("同步完成，共%d件商品，成功%d件", products.size(), successCount);
            log.info(resultMsg);
            return Result.success(resultMsg);
        } catch (Exception e) {
            log.error("同步商品到ES失败", e);
            return Result.error("同步失败：" + e.getMessage());
        }
    }

    /**
     * 同步所有求购信息到ES
     */
    @Override
    public Result<String> syncAllPurchaseRequestsToEs() {
        try {
            log.info("开始同步求购信息到ElasticSearch...");

            // 查询所有进行中的求购信息
            LambdaQueryWrapper<PurchaseRequest> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PurchaseRequest::getStatus, 1) // 进行中状态
                    .eq(PurchaseRequest::getIsActive, 1); // 有效

            List<PurchaseRequest> purchaseRequests = purchaseRequestMapper.selectList(queryWrapper);
            log.info("共找到{}条进行中的求购信息", purchaseRequests.size());

            int successCount = 0;
            for (PurchaseRequest purchaseRequest : purchaseRequests) {
                try {
                    // 构建ES文档
                    PurchaseRequestDocument document = convertToPurchaseRequestDocument(purchaseRequest);

                    // 保存到ES
                    boolean success = purchaseRequestEsRepository.savePurchaseRequest(document);
                    if (success) {
                        successCount++;
                    }
                } catch (Exception e) {
                    log.error("同步求购信息#{}到ES失败", purchaseRequest.getId(), e);
                }
            }

            String resultMsg = String.format("同步完成，共%d条求购信息，成功%d条", purchaseRequests.size(), successCount);
            log.info(resultMsg);
            return Result.success(resultMsg);
        } catch (Exception e) {
            log.error("同步求购信息到ES失败", e);
            return Result.error("同步失败：" + e.getMessage());
        }
    }

    /**
     * 将商品实体转换为ES文档
     */
    private ProductDocument convertToDocument(Product product) {
        if (product == null) {
            return null;
        }

        // 查询卖家信息
        User seller = userMapper.selectById(product.getSellerId());

        // 查询学校信息
        School school = schoolMapper.selectById(product.getSchoolId());

        // 查询商品图片
        LambdaQueryWrapper<ProductImages> imageQueryWrapper = new LambdaQueryWrapper<>();
        imageQueryWrapper.eq(ProductImages::getProductId, product.getId())
                .eq(ProductImages::getIsMain, 1) // 获取主图（isMain=1）
                .or()
                .eq(ProductImages::getProductId, product.getId())
                .orderByAsc(ProductImages::getSortOrder) // 如果没有主图，获取排序最靠前的图片
                .last("LIMIT 1");

        ProductImages mainImage = productImageMapper.selectOne(imageQueryWrapper);

        // 获取所有图片
        LambdaQueryWrapper<ProductImages> allImagesQueryWrapper = new LambdaQueryWrapper<>();
        allImagesQueryWrapper.eq(ProductImages::getProductId, product.getId())
                .orderByDesc(ProductImages::getIsMain)
                .orderByAsc(ProductImages::getSortOrder);

        List<ProductImages> images = productImageMapper.selectList(allImagesQueryWrapper);

        ProductDocument document = new ProductDocument();
        document.setId(product.getId());
        document.setName(product.getName());
        document.setPrice(product.getPrice());
        document.setOriginalPrice(product.getOriginalPrice());
        document.setDescription(product.getDescription());
        document.setCondition(product.getCondition());
        document.setSellerId(product.getSellerId());
        document.setSchoolId(product.getSchoolId());
        document.setCategoryId(product.getCategoryId());
        document.setLongitude(product.getLongitude());
        document.setLatitude(product.getLatitude());
        document.setViews(product.getViews());
        document.setStatus(product.getStatus());
        document.setImages(images.stream().map(ProductImages::getImageUrl).toArray(String[]::new));
        document.setMainImage(mainImage.getImageUrl());
        

        // 设置商品主图
        if (mainImage != null) {
            document.setMainImage(mainImage.getImageUrl());
        }

        // 设置所有图片
        if (images != null && !images.isEmpty()) {
            document.setImages(images.stream().map(ProductImages::getImageUrl).toArray(String[]::new));
        }

        // 将日期时间字段转换为时间戳
        if (product.getCreatedAt() != null) {
            Long createdAtTimestamp = product.getCreatedAt()
                    .atZone(java.time.ZoneId.systemDefault())
                    .toInstant()
                    .toEpochMilli();
            document.setCreatedAt(createdAtTimestamp);
        }

        if (product.getUpdatedAt() != null) {
            Long updatedAtTimestamp = product.getUpdatedAt()
                    .atZone(java.time.ZoneId.systemDefault())
                    .toInstant()
                    .toEpochMilli();
            document.setUpdatedAt(updatedAtTimestamp);
        }

        // 设置卖家信息
        if (seller != null) {
            document.setSellerName(seller.getNickname());
            document.setSellerAvatar(seller.getAvatar());
        }

        // 设置学校信息
        if (school != null) {
            document.setSchoolName(school.getName());
        }

        return document;
    }

    /**
     * 将ES文档转换为VO
     */
    private ProductVO convertToProductVO(ProductDocument document) {
        if (document == null) {
            return null;
        }

        ProductVO vo = new ProductVO();
        vo.setId(document.getId());
        vo.setName(document.getName());
        vo.setPrice(document.getPrice());
        vo.setOriginalPrice(document.getOriginalPrice());
        vo.setDescription(document.getDescription());
        vo.setCondition(document.getCondition());
        vo.setSellerId(document.getSellerId());
        vo.setSellerName(document.getSellerName());
        vo.setSellerAvatar(document.getSellerAvatar());
        vo.setSchoolId(document.getSchoolId());
        vo.setSchoolName(document.getSchoolName());
        vo.setCategoryId(document.getCategoryId());
        vo.setCategoryName(document.getCategoryName());
        vo.setViews(document.getViews());
        vo.setMainImage(document.getMainImage());

        // 处理创建时间和更新时间
        if (document.getCreatedAt() != null) {
            LocalDateTime createdAt = LocalDateTime.ofInstant(
                    Instant.ofEpochMilli(document.getCreatedAt()),
                    ZoneId.systemDefault());
            vo.setCreatedAt(createdAt);
        }

        if (document.getUpdatedAt() != null) {
            LocalDateTime updatedAt = LocalDateTime.ofInstant(
                    Instant.ofEpochMilli(document.getUpdatedAt()),
                    ZoneId.systemDefault());
            vo.setUpdatedAt(updatedAt);
        }

        return vo;
    }

    /**
     * 将实体转换为VO
     */
    private ProductVO convertEntityToVO(Product product) {
        if (product == null) {
            return null;
        }

        // 查询卖家信息
        User seller = userMapper.selectById(product.getSellerId());

        // 查询学校信息
        School school = schoolMapper.selectById(product.getSchoolId());

        // 查询商品图片
        LambdaQueryWrapper<ProductImages> imageQueryWrapper = new LambdaQueryWrapper<>();
        imageQueryWrapper.eq(ProductImages::getProductId, product.getId())
                .eq(ProductImages::getIsMain, 1) // 获取主图（isMain=1）
                .or()
                .eq(ProductImages::getProductId, product.getId())
                .orderByAsc(ProductImages::getSortOrder) // 如果没有主图，获取排序最靠前的图片
                .last("LIMIT 1");

        ProductImages mainImage = productImageMapper.selectOne(imageQueryWrapper);

        // 获取所有图片
        LambdaQueryWrapper<ProductImages> allImagesQueryWrapper = new LambdaQueryWrapper<>();
        allImagesQueryWrapper.eq(ProductImages::getProductId, product.getId())
                .orderByDesc(ProductImages::getIsMain)
                .orderByAsc(ProductImages::getSortOrder);

        List<ProductImages> images = productImageMapper.selectList(allImagesQueryWrapper);

        ProductVO vo = new ProductVO();
        vo.setId(product.getId());
        vo.setName(product.getName());
        vo.setPrice(product.getPrice());
        vo.setOriginalPrice(product.getOriginalPrice());
        vo.setDescription(product.getDescription());
        vo.setCondition(product.getCondition());
        vo.setSellerId(product.getSellerId());
        vo.setSchoolId(product.getSchoolId());
        vo.setCategoryId(product.getCategoryId());
        vo.setViews(product.getViews());

        // 设置商品主图
        if (mainImage != null) {
            vo.setMainImage(mainImage.getImageUrl());
        }

        // 获取所有图片
        if (images != null && !images.isEmpty()) {
            vo.setImages(images.stream().map(ProductImages::getImageUrl).collect(Collectors.toList()));
        }

        // 设置卖家信息
        if (seller != null) {
            vo.setSellerName(seller.getNickname());
            vo.setSellerAvatar(seller.getAvatar());
        }

        // 设置学校信息
        if (school != null) {
            vo.setSchoolName(school.getName());
        }

        return vo;
    }

    @Override
    public Result<Map<String, Object>> searchPurchaseRequests(String keyword, Integer page, Integer pageSize,
            String sortBy, Long categoryId, Long schoolId,
            BigDecimal minBudget, BigDecimal maxBudget) {
        if (keyword == null || keyword.isEmpty()) {
            return Result.error("搜索关键词不能为空");
        }

        // 设置默认分页参数
        page = page != null ? page : 1;
        pageSize = pageSize != null ? pageSize : 12;

        try {
            // 使用ES仓库进行搜索
            List<PurchaseRequestDocument> purchaseRequestDocuments = purchaseRequestEsRepository.searchPurchaseRequests(
                    keyword, schoolId, categoryId, (page - 1) * pageSize, pageSize);

            // 如果ES中没有找到数据，尝试从数据库中搜索
            if (purchaseRequestDocuments == null || purchaseRequestDocuments.isEmpty()) {
                log.info("ES中未找到匹配的求购信息数据，尝试从数据库搜索");
                return fallbackSearchPurchaseRequests(keyword, page, pageSize, sortBy, categoryId, schoolId, minBudget,
                        maxBudget);
            }

            // 转换为VO
            List<PurchaseRequestVO> purchaseRequestVOs = purchaseRequestDocuments.stream()
                    .map(this::convertToPurchaseRequestVO)
                    .collect(Collectors.toList());

            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", purchaseRequestVOs);
            result.put("total", purchaseRequestVOs.size());

            return Result.success(result);
        } catch (Exception e) {
            log.error("搜索求购信息失败", e);
            // 降级处理：如果ES搜索失败，尝试使用数据库搜索
            return fallbackSearchPurchaseRequests(keyword, page, pageSize, sortBy, categoryId, schoolId, minBudget,
                    maxBudget);
        }
    }

    /**
     * 降级处理：使用数据库搜索求购信息
     * 如果数据库中找到结果，同时更新到ES中
     */
    private Result<Map<String, Object>> fallbackSearchPurchaseRequests(String keyword, Integer page, Integer pageSize,
            String sortBy, Long categoryId, Long schoolId,
            BigDecimal minBudget, BigDecimal maxBudget) {
        try {
            log.warn("ES搜索失败或未找到数据，降级为数据库搜索");

            // 创建查询条件
            LambdaQueryWrapper<PurchaseRequest> queryWrapper = new LambdaQueryWrapper<>();

            // 关键词搜索
            queryWrapper.like(PurchaseRequest::getTitle, keyword)
                    .or()
                    .like(PurchaseRequest::getDescription, keyword);

            // 分类筛选
            if (categoryId != null) {
                queryWrapper.eq(PurchaseRequest::getCategoryId, categoryId);
            }

            // 学校筛选
            if (schoolId != null) {
                queryWrapper.eq(PurchaseRequest::getSchoolId, schoolId);
            }

            // 价格范围筛选
            if (minBudget != null) {
                queryWrapper.ge(PurchaseRequest::getBudget, minBudget);
            }

            if (maxBudget != null) {
                queryWrapper.le(PurchaseRequest::getBudget, maxBudget);
            }

            // 状态筛选 - 只查询进行中的求购
            queryWrapper.eq(PurchaseRequest::getStatus, 1)
                    .eq(PurchaseRequest::getIsActive, 1);

            // 排序
            if (sortBy != null) {
                switch (sortBy) {
                    case "priceAsc":
                        queryWrapper.orderByAsc(PurchaseRequest::getBudget);
                        break;
                    case "priceDesc":
                        queryWrapper.orderByDesc(PurchaseRequest::getBudget);
                        break;
                    case "newest":
                        queryWrapper.orderByDesc(PurchaseRequest::getCreateTime);
                        break;
                    case "views":
                        queryWrapper.orderByDesc(PurchaseRequest::getViews);
                        break;
                    default:
                        queryWrapper.orderByDesc(PurchaseRequest::getCreateTime);
                        break;
                }
            } else {
                queryWrapper.orderByDesc(PurchaseRequest::getCreateTime);
            }

            // 执行分页查询
            Page<PurchaseRequest> purchaseRequestPage = new Page<>(page, pageSize);
            Page<PurchaseRequest> resultPage = purchaseRequestMapper.selectPage(purchaseRequestPage, queryWrapper);

            // 检查是否有搜索结果
            if (resultPage.getRecords() != null && !resultPage.getRecords().isEmpty()) {
                // 异步更新搜索结果到ES
                new Thread(() -> {
                    try {
                        log.info("开始将数据库搜索结果同步到ES，共{}条", resultPage.getRecords().size());
                        for (PurchaseRequest purchaseRequest : resultPage.getRecords()) {
                            createOrUpdatePurchaseRequestIndex(purchaseRequest.getId());
                        }
                        log.info("数据库搜索结果同步到ES完成");
                    } catch (Exception e) {
                        log.error("同步数据库搜索结果到ES失败", e);
                    }
                }).start();
            }

            // 转换为VO
            List<PurchaseRequestVO> purchaseRequestVOs = resultPage.getRecords().stream()
                    .map(this::convertPurchaseRequestEntityToVO)
                    .collect(Collectors.toList());

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", purchaseRequestVOs);
            result.put("total", resultPage.getTotal());

            return Result.success(result);
        } catch (Exception e) {
            log.error("数据库搜索求购信息失败", e);
            return Result.error("搜索求购信息失败：" + e.getMessage());
        }
    }

    /**
     * 创建或更新求购信息索引
     */
    public void createOrUpdatePurchaseRequestIndex(Long purchaseRequestId) {
        try {
            // 查询求购信息详情
            PurchaseRequest purchaseRequest = purchaseRequestMapper.selectById(purchaseRequestId);
            if (purchaseRequest == null) {
                log.error("求购信息不存在，无法索引，purchaseRequestId: {}", purchaseRequestId);
                return;
            }

            // 转换为ES文档
            PurchaseRequestDocument document = convertToPurchaseRequestDocument(purchaseRequest);

            // 保存到ES
            boolean success = purchaseRequestEsRepository.savePurchaseRequest(document);
            if (success) {
                log.info("求购信息索引创建/更新成功，purchaseRequestId: {}", purchaseRequestId);
            } else {
                log.error("求购信息索引创建/更新失败，purchaseRequestId: {}", purchaseRequestId);
            }
        } catch (Exception e) {
            log.error("创建求购信息索引失败，purchaseRequestId: {}", purchaseRequestId, e);
        }
    }

    /**
     * 将求购信息实体转换为ES文档
     */
    private PurchaseRequestDocument convertToPurchaseRequestDocument(PurchaseRequest purchaseRequest) {
        if (purchaseRequest == null) {
            return null;
        }

        // 查询发布者信息
        User user = userMapper.selectById(purchaseRequest.getUserId());

        // 查询学校信息
        School school = schoolMapper.selectById(purchaseRequest.getSchoolId());

        PurchaseRequestDocument document = new PurchaseRequestDocument();
        document.setId(purchaseRequest.getId());
        document.setTitle(purchaseRequest.getTitle());
        document.setDescription(purchaseRequest.getDescription());
        document.setBudget(purchaseRequest.getBudget());
        document.setCategoryId(purchaseRequest.getCategoryId());
        document.setUserId(purchaseRequest.getUserId());
        document.setSchoolId(purchaseRequest.getSchoolId());
        document.setContactInfo(purchaseRequest.getContactInfo());
        document.setViews(purchaseRequest.getViews());
        document.setStatus(purchaseRequest.getStatus());
        document.setIsActive(purchaseRequest.getIsActive());

        // 将日期时间字段转换为时间戳
        if (purchaseRequest.getCreateTime() != null) {
            Long createTimeTimestamp = purchaseRequest.getCreateTime()
                    .atZone(ZoneId.systemDefault())
                    .toInstant()
                    .toEpochMilli();
            document.setCreateTime(createTimeTimestamp);
        }

        if (purchaseRequest.getUpdateTime() != null) {
            Long updateTimeTimestamp = purchaseRequest.getUpdateTime()
                    .atZone(ZoneId.systemDefault())
                    .toInstant()
                    .toEpochMilli();
            document.setUpdateTime(updateTimeTimestamp);
        }

        if (purchaseRequest.getExpireTime() != null) {
            Long expireTimeTimestamp = purchaseRequest.getExpireTime()
                    .atZone(ZoneId.systemDefault())
                    .toInstant()
                    .toEpochMilli();
            document.setExpireTime(expireTimeTimestamp);
        }

        // 设置用户信息
        if (user != null) {
            document.setUserName(user.getNickname());
            document.setUserAvatar(user.getAvatar());
        }

        // 设置学校信息
        if (school != null) {
            document.setSchoolName(school.getName());
        }

        return document;
    }

    /**
     * 将ES文档转换为求购信息VO
     */
    private PurchaseRequestVO convertToPurchaseRequestVO(PurchaseRequestDocument document) {
        if (document == null) {
            return null;
        }

        PurchaseRequestVO vo = new PurchaseRequestVO();
        vo.setId(document.getId());
        vo.setTitle(document.getTitle());
        vo.setDescription(document.getDescription());
        vo.setBudget(document.getBudget());
        vo.setCategoryId(document.getCategoryId());
        vo.setCategoryName(document.getCategoryName());
        vo.setUserId(document.getUserId());
        vo.setUserName(document.getUserName());
        vo.setUserAvatar(document.getUserAvatar());
        vo.setSchoolId(document.getSchoolId());
        vo.setSchoolName(document.getSchoolName());
        vo.setContactInfo(document.getContactInfo());
        vo.setViews(document.getViews());

        // 处理创建时间和更新时间
        if (document.getCreateTime() != null) {
            LocalDateTime createTime = LocalDateTime.ofInstant(
                    Instant.ofEpochMilli(document.getCreateTime()),
                    ZoneId.systemDefault());
            vo.setCreateTime(createTime);
        }

        if (document.getUpdateTime() != null) {
            LocalDateTime updateTime = LocalDateTime.ofInstant(
                    Instant.ofEpochMilli(document.getUpdateTime()),
                    ZoneId.systemDefault());
            vo.setUpdateTime(updateTime);
        }

        if (document.getExpireTime() != null) {
            LocalDateTime expireTime = LocalDateTime.ofInstant(
                    Instant.ofEpochMilli(document.getExpireTime()),
                    ZoneId.systemDefault());
            vo.setExpireTime(expireTime);
        }

        return vo;
    }

    /**
     * 将求购信息实体转换为VO
     */
    private PurchaseRequestVO convertPurchaseRequestEntityToVO(PurchaseRequest purchaseRequest) {
        if (purchaseRequest == null) {
            return null;
        }

        // 查询发布者信息
        User user = userMapper.selectById(purchaseRequest.getUserId());

        // 查询学校信息
        School school = schoolMapper.selectById(purchaseRequest.getSchoolId());

        PurchaseRequestVO vo = new PurchaseRequestVO();
        vo.setId(purchaseRequest.getId());
        vo.setTitle(purchaseRequest.getTitle());
        vo.setDescription(purchaseRequest.getDescription());
        vo.setBudget(purchaseRequest.getBudget());
        vo.setCategoryId(purchaseRequest.getCategoryId());
        vo.setUserId(purchaseRequest.getUserId());
        vo.setSchoolId(purchaseRequest.getSchoolId());
        vo.setContactInfo(purchaseRequest.getContactInfo());
        vo.setViews(purchaseRequest.getViews());
        vo.setCreateTime(purchaseRequest.getCreateTime());
        vo.setUpdateTime(purchaseRequest.getUpdateTime());
        vo.setExpireTime(purchaseRequest.getExpireTime());


        // 设置用户信息
        if (user != null) {
            vo.setUserName(user.getNickname());
            vo.setUserAvatar(user.getAvatar());
        }

        // 设置学校信息
        if (school != null) {
            vo.setSchoolName(school.getName());
        }

        return vo;
    }
}